package com.stone.framework.auth.service.impl;

import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.stone.framework.auth.client.UserClient;
import com.stone.framework.auth.service.LoginService;
import com.stone.framework.core.cache.AuthConstant;
import com.stone.framework.core.exception.BusinessException;
import com.stone.framework.core.model.UserInfo;
import com.stone.framework.core.model.UserInfo.Terminal;
import com.stone.framework.core.util.Jwts;
import com.stone.framework.core.util.RedisUtil;
import com.stone.framework.message.auth.LoginReqBody;
import com.stone.framework.message.user.TokenInfoResBody;
import com.wf.captcha.SpecCaptcha;

@Service
@Transactional(readOnly = true)
public class LoginServiceImpl implements LoginService {

    @Autowired
    private UserClient userClient;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public String login(LoginReqBody reqBody) {
        checkCaptcha(reqBody.getCaptchaKey(), reqBody.getCaptcha());
        UsernamePasswordToken token = new UsernamePasswordToken(reqBody.getUsername(), reqBody.getPassword());
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
        } catch (Exception e) {
            throw new BusinessException("用户名或密码错误", e);
        }

        return this.getToken(reqBody.getUsername(), reqBody.getTerminal());
    }

    @Override
    public String getToken(String username, String terminal) {
        TokenInfoResBody resBody = userClient.getTokenInfo(username);
        String cname = resBody.getCname();
        String deptCode = resBody.getDeptCode();
        List<String> roles = resBody.getRoles();
        List<String> permissions = resBody.getPermissions();

        UserInfo userInfo = new UserInfo().setName(username).setCname(cname).setDept(deptCode).setRoles(roles)
            .setPerms(permissions).setTerm(Terminal.valueOf(terminal));

        return Jwts.sign(userInfo);
    }

    @Override
    public String buildCaptcha(String uuid) {
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 5);
        String value = specCaptcha.text();
        redisUtil.set(AuthConstant.CAPTCHA, uuid, value, 60L);
        return specCaptcha.toBase64();
    }

    private void checkCaptcha(String key, String value) {
        String captcha = redisUtil.get(AuthConstant.CAPTCHA, key);
        if (captcha == null || "".equals(captcha)) {
            throw new BusinessException("验证码已失效");
        }
        if (!captcha.equalsIgnoreCase(value)) {
            throw new BusinessException("验证码错误");
        }
    }

}
